<?php
declare(strict_types=1);
namespace Hangpu888\Hpadmin\controller;

use Hangpu888\Hpadmin\Controller;
use Hangpu888\Hpadmin\model\AuthRule as ModelAuthRule;
use Hangpu888\Hpadmin\utils\builder\FormBuilder;
use Hangpu888\Hpadmin\utils\builder\ListBuilder;
use Hangpu888\Hpadmin\utils\Json;
use Hangpu888\Hpadmin\validate\AuthRule as ValidateAuthRule;

class AuthRule extends Controller
{
    /**
     * 显示列表
     *
     * @return void
     */
    public function index()
    {
        $list = ModelAuthRule::where(['pid' => ''])->order('sort asc,id asc')->select()->toArray();
        $list = $this->getAuthRule($list);
        $builder = new ListBuilder;
        $data = $builder
            ->setChildren('/hpadmin/AuthRule/getChildren', 'get', 'id')
            ->addColumn('rightButtonList', '操作', [
                'type'              => 'template',
                'template'          => 'rightButtonList'
            ])
            ->addTopButton('add', '添加', [
                'api'               => '/hpadmin/AuthRule/add',
                'title'             => '添加权限菜单',
                'method'            => 'get',
                'type'              => 'modal',
            ])
            ->addRightButton('edit', '编辑', [
                'api'               => '/hpadmin/AuthRule/edit',
                'title'             => '修改权限菜单',
                'method'            => 'get',
                'type'              => 'modal',
            ], [
                'type'              => 'text',
            ])
            ->addRightButton('del', '删除', [
                'api'               => '/hpadmin/AuthRule/del',
                'method'            => 'delete',
                'title'             => '温馨提示',
                'content'           => '是否确认删除该数据？',
                'type'              => 'confirm',
            ], [
                'type'              => 'text',
            ], [
                'type'              => 'warning',
            ])
            ->addColumn('path_text', '路由')
            ->addColumn('title', '名称')
            ->addColumn('show_text', '状态', [
                'width'             => '100'
            ])
            ->addColumn('type_text', '类型', [
                'width'             => '150'
            ])
            ->addColumn('method', '请求类型')
            ->setData($list)
            ->create();
        return Json::successRes($data);
    }

    /**
     * 显示子数据
     *
     * @return void
     */
    public function getChildren()
    {
        $id = request()->get('id');
        $info = ModelAuthRule::where(['id' => $id])->find();
        if (!$info) {
            return Json::fail('找不到该数据');
        }
        $path = $info->path;
        $list = ModelAuthRule::where(['pid' => $path])->select()->toArray();
        $list = $this->getAuthRule($list);
        return Json::successRes($list);
    }

    /**
     * 添加/视图
     *
     * @return void
     */
    public function add()
    {
        try {
            $client                             = request()->get('client', 'admin');
            if (request()->method() == 'POST') {
                // 获取数据
                $post                           = request()->post();
    
                // 数据验证
                hpValidate(new ValidateAuthRule,$post);
    
                // 重组数据
                $authRuleModel                  = new ModelAuthRule;
                $data['pid']                    = $post['pid'] && is_array($post['pid']) ? end($post['pid']) : $post['pid'];
                $data['title']                  = $post['title'];
                $data['path']                   = $post['path'];
                $data['params']                 = $post['params'];
                $data['method']                 = is_array($post['method']) ? implode(',', $post['method']) : $post['method'];
                $data['type']                   = $post['type'];
                $data['icon']                   = $post['icon'];
                $data['show']                   = $post['show'];
                $data['sort']                   = $post['sort'];
                $data['remote']                 = isset($post['remote']) ? $post['remote'] : '';
                $data['client']                 = $client;
                foreach ($data as $field => $value) {
                    $authRuleModel->$field  = $value;
                }
                if ($authRuleModel->save()) {
                    return Json::success('添加成功');
                } else {
                    return Json::fail('添加失败');
                }
            } else {
                $authRuleModel = new ModelAuthRule;
                $getFormData = $authRuleModel->getFormData();
                $builder = new FormBuilder;
                $data = $builder
                    ->setMethod('POST')
                    ->setAction("/hpadmin/AuthRule/add?client={$client}")
                    ->addRow('pid', 'cascader', '父级菜单', [], [
                        'props'                 => [
                            'props'             => [
                                'checkStrictly' => true,
                            ],
                        ],
                        'options'               => $getFormData['parent'],
                        'placeholder'           => '如不选择则是顶级菜单',
                        'col'                   => [
                            'span'              => 12
                        ],
                    ])
                    ->addRow('type', 'select', '菜单类型', '', [
                        'options'               => $getFormData['type'],
                        'col'                   => [
                            'span'              => 12
                        ],
                        'control'               => [
                            [
                                'value'         => 'component',
                                'where'         => '==',
                                'rule'          => [
                                    [
                                        'type'  => 'input',
                                        'title' => '远程组件',
                                        'field' => 'remote',
                                        'value' => '',
                                        'props' => [
                                            'type'  => 'text',
                                            'placeholder'   => '请输入远程组件',
                                        ],
                                    ],
                                ],
                            ],
                        ],
                    ])
                    ->addRow('title', 'input', '菜单名称', '', [
                        'col'                   => [
                            'span'              => 12
                        ],
                    ])
                    ->addRow('path', 'input', '权限路由', '', [
                        'placeholder'           => '控制器/方法',
                        'col'                   => [
                            'span'              => 12
                        ],
                    ])
                    ->addRow('show', 'radio', '显示隐藏', 1, [
                        'options'               => $getFormData['show'],
                        'col'                   => [
                            'span'              => 12
                        ],
                    ])
                    ->addRow('method', 'checkbox', '请求类型', ['GET'], [
                        'options'               => $getFormData['methods'],
                        'col'                   => [
                            'span'              => 12
                        ],
                    ])
                    ->addRow('icon', 'custom', '菜单图标', '', [
                        'type'                  => 'icons',
                        'extra'                 => [
                            'col'               => [
                                'span'          => 12
                            ],
                        ],
                    ])
                    ->addRow('sort', 'input', '菜单排序', '100', [
                        'col'                   => [
                            'span'              => 12
                        ],
                    ])
                    ->addRow('params', 'input', '附带参数', '', [
                        'placeholder'           => '附带地址栏参数（选填），格式:name=楚羽幽&sex=男',
                    ])
                    ->create();
                return Json::successRes($data);
            }
        } catch (\Throwable $e) {
            return Json::fail($e->getMessage());
        }
    }

    /**
     * 编辑/视图
     *
     * @return void
     */
    public function edit()
    {
        try {
            $id                                 = request()->get('id');
            $client                             = request()->get('client', 'admin');
            if (request()->method() == 'PUT') {
                // 获取数据
                $post                           = request()->post();

                // 数据验证
                hpValidate(new ValidateAuthRule,$post);
                
                // 重组数据
                $authRuleModel                  = ModelAuthRule::where(['id' => $id])->find();
                $data['pid']                    = $post['pid'] && is_array($post['pid']) ? end($post['pid']) : $post['pid'];
                $data['title']                  = $post['title'];
                $data['path']                   = $post['path'];
                $data['params']                 = $post['params'];
                $data['method']                 = is_array($post['method']) ? implode(',', $post['method']) : $post['method'];
                $data['type']                   = $post['type'];
                $data['icon']                   = $post['icon'];
                $data['show']                   = $post['show'];
                $data['sort']                   = $post['sort'];
                $data['remote']                 = isset($post['remote']) ? $post['remote'] : '';
                $data['client']                 = $client;
                foreach ($data as $field => $value) {
                    $authRuleModel->$field  = $value;
                }
                if ($authRuleModel->save()) {
                    return Json::success('修改成功');
                } else {
                    return Json::fail('修改失败');
                }
            } else {
                $map['id'] = $id;
                $response = ModelAuthRule::where($map)->find();
                if (!$response) {
                    return Json::fail('找不到该数据');
                }
                $response = $response->toArray();
                $response['method'] = explode(',', $response['method']);
                $authRuleModel = new ModelAuthRule;
                $getFormData = $authRuleModel->getFormData();
                $builder = new FormBuilder;
                $data = $builder
                    ->setMethod('put')
                    ->setAction("/hpadmin/AuthRule/edit?client={$client}")
                    ->addRow('pid', 'cascader', '父级菜单', [], [
                        'props'                 => [
                            'props'             => [
                                'checkStrictly' => true,
                            ],
                        ],
                        'options'               => $getFormData['parent'],
                        'placeholder'           => '如不选择则是顶级菜单',
                        'col'                   => [
                            'span'              => 12
                        ],
                    ])
                    ->addRow('type', 'select', '菜单类型', '', [
                        'options'               => $getFormData['type'],
                        'col'                   => [
                            'span'              => 12
                        ],
                        'control'               => [
                            [
                                'value'         => 'component',
                                'where'         => '==',
                                'rule'          => [
                                    [
                                        'type'  => 'input',
                                        'title' => '远程组件',
                                        'field' => 'remote',
                                        'value' => '',
                                        'props' => [
                                            'type'  => 'text',
                                            'placeholder'   => '请输入远程组件',
                                        ],
                                    ],
                                ],
                            ],
                        ],
                    ])
                    ->addRow('title', 'input', '菜单名称', '', [
                        'col'                   => [
                            'span'              => 12
                        ],
                    ])
                    ->addRow('path', 'input', '权限路由', '', [
                        'placeholder'           => '控制器/方法',
                        'col'                   => [
                            'span'              => 12
                        ],
                    ])
                    ->addRow('show', 'radio', '显示隐藏', 1, [
                        'options'               => $getFormData['show'],
                        'col'                   => [
                            'span'              => 12
                        ],
                    ])
                    ->addRow('method', 'checkbox', '请求类型', ['GET'], [
                        'options'               => $getFormData['methods'],
                        'col'                   => [
                            'span'              => 12
                        ],
                    ])
                    ->addRow('icon', 'custom', '菜单图标', '', [
                        'type'                  => 'icons',
                        'extra'                 => [
                            'col'               => [
                                'span'          => 12
                            ],
                        ],
                    ])
                    ->addRow('sort', 'input', '菜单排序', '100', [
                        'col'                   => [
                            'span'              => 12
                        ],
                    ])
                    ->addRow('params', 'input', '附带参数', '', [
                        'placeholder'           => '附带地址栏参数（选填），格式:name=楚羽幽&sex=男',
                    ])
                    ->setFormData($response)
                    ->create();
                return Json::successRes($data);
            }
        } catch (\Throwable $e) {
            return Json::fail($e->getMessage());
        }
    }

    /**
     * 删除
     *
     * @return void
     */
    public function del()
    {
        $id = request()->get('id');
        $authRuleModel = ModelAuthRule::where(['id' => $id])->find();
        if (!$authRuleModel) {
            return Json::fail('找不到该权限菜单');
        }
        // 验证子权限
        $findAuth = ModelAuthRule::where(['pid' => $authRuleModel->path])->find();
        if ($findAuth) {
            return Json::fail('该权限下有子权限，禁止删除');
        }
        if ($authRuleModel->delete()) {
            return Json::success('删除成功');
        } else {
            return Json::fail('删除失败');
        }
    }

    /**
     * 获取重组后的权限数据
     *
     * @param array $data
     * @return array
     */
    private function getAuthRule(array $data): array
    {
        // 是否显示：0隐藏，1显示（仅针对1-2-3级菜单）
        $show = ['隐藏', '显示'];
        // 类型：form表单页，list表格页，welcome本地欢迎页，remote远程组件，router纯接口，group分组
        $type = [
            'form'          => '表单类型',
            'list'          => '表格类型',
            'welcome'       => '欢迎页面',
            'remote'        => '远程组件',
            'router'        => '接口类型',
            'group'         => '菜单分组'
        ];
        foreach ($data as $key => $value) {
            $data[$key]['path_text'] = "{$value['client']}/{$value['path']}";
            $data[$key]['show_text'] = $show[$value['show']];
            $data[$key]['type_text'] = $type[$value['type']];
            // 判断是否有子权限
            $bool = ModelAuthRule::where(['pid' => $value['path']])->count();
            $data[$key]['hasChildren'] = $bool ? true : false;
        }
        return $data;
    }
}
